package com.yiyuwanglu.basecore.dao.mongodb;

import java.util.Collection;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.mapreduce.GroupBy;
import org.springframework.data.mongodb.core.mapreduce.GroupByResults;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Repository;

import com.yiyuwanglu.basecore.page.Page;

@Repository(value = "mongoDBBaseDaoImpl")
public class MongoDBBaseDaoImpl implements com.yiyuwanglu.basecore.dao.MongoDBBaseDao {
	@Autowired
	@Qualifier("mongoTemplate")
	protected MongoTemplate mongoTemplate;

	/**
	 * 根据主键id返回对象
	 * 
	 * @param id
	 *            唯一标识
	 * @return T 对象
	 */
	public <T> T findById(Class<T> entityClass, String id) {
		return this.mongoTemplate.findById(id, entityClass);
		
	}
	/**
	 * 根据查询条件查询
	 * 
	 * @param id
	 *            唯一标识
	 * @return T 对象
	 */
	public <T> List<T> find(Query query,Class<T> entityClass, String collectionName) {
		return this.mongoTemplate.find(query, entityClass, collectionName);
		
	}
	/**
	 * 根据类获取全部的对象列表
	 * 
	 * @param entityClass
	 *            返回类型
	 * @return List<T> 返回对象列表
	 */
	public <T> List<T> findAll(Class<T> entityClass) {
		return this.mongoTemplate.findAll(entityClass);
	}
	
	/**
	 * 根据类获取全部的对象列表
	 * 
	 * @param entityClass
	 *            返回类型
	 * @param collectionName
	 *            集合名称            
	 * @return List<T> 返回对象列表
	 */
	public <T> List<T> findAll(Class<T> entityClass,String collectionName) {
		return this.mongoTemplate.findAll(entityClass,collectionName);
	}

	/**
	 * 删除一个对象
	 * 
	 * @param obj
	 *            要删除的Mongo对象
	 */
	public void remove(Object obj) {
		this.mongoTemplate.remove(obj);
	}

	/**
	 * 添加对象
	 * 
	 * @param obj
	 *            要添加的Mongo对象
	 */
	public void add(Object obj) {
		this.mongoTemplate.insert(obj);

	}
	/**
	 * 添加对象
	 * 
	 * @param obj
	 *            要添加的Mongo对象
	 * @param collectionName
	 * 			  集合名称
	 */
	public void add(Object obj,String collectionName) {
		this.mongoTemplate.insert(obj,collectionName);

	}
	/**
	 * 添加对象
	 * 
	 * @param obj
	 *            要添加的Mongo对象
	 */
	public void add(Map<String, Object> map, String collectionName) {
		
		this.mongoTemplate.insert(map, collectionName);;

	}

	/**
	 * 修改对象
	 * 
	 * @param obj
	 *            要修改的Mongo对象
	 */
	public void saveOrUpdate(Object obj) {
		this.mongoTemplate.save(obj);
	}
	/**
	 * 修改对象
	 * 
	 * @param obj
	 *            要修改的Mongo对象
	 * @param collectionName
	 *            集合名称     
	 */
	public void saveOrUpdate(Object obj,String collectionName) {
		this.mongoTemplate.save(obj, collectionName);;
	}

	/**
	 * @param query
	 * 			查询条件
	 * @param update
	 * 			修改对象
	 * @param collectionName
	 * 			集合名词
	 */		
	public void updateMulti(Query query,Update update,String collectionName) {
		this.mongoTemplate.updateMulti(query, update, collectionName);
	}


	/**
	 * 查询并分页
	 * 
	 * @param entityClass
	 *            对象类型
	 * @param query
	 *            查询条件
	 * @param page
	 *            分页
	 * @return
	 */
	public <T> List<T> findByQuery(Class<T> entityClass, Query query, Page page) {
		Long count = this.count(entityClass, query);
		page.setPageCount(count.intValue());
		int pageNumber = page.getPageNo();
		int pageSize = page.getPageCount();
		query.skip((pageNumber - 1) * pageSize).limit(pageSize);
		return this.mongoTemplate.find(query, entityClass);
	}
	/**
	 * 查询并分页
	 * 
	 * @param entityClass
	 *            对象类型
	 * @param query
	 *            查询条件
	 * @param collectionName
	 *            
	 * @return
	 */
	public <T> List<T> findByQuery(Class<T> entityClass, Query query,String collectionName) {
		return this.mongoTemplate.find(query, entityClass, collectionName);
	}
	/**
	 * 查询并分页
	 * 
	 * @param entityClass
	 *            对象类型
	 * @param query
	 *            查询条件
	 * @param collectionName
	 *            
	 * @return
	 */
	public <T> List<T> findByQuery(Class<T> entityClass, Query query,String collectionName,Page page) {
		Long count = this.count(collectionName, query);
		page.setPageCount(count.intValue());
		int pageNumber = page.getPageNo();
		int pageSize = page.getPageCount();
		query.skip((pageNumber - 1) * pageSize).limit(pageSize);
		return this.mongoTemplate.find(query, entityClass, collectionName);

	}
	/**
	 * 
	 * @param entityClass
	 *            查询对象
	 * @param query
	 *            查询条件
	 * @return
	 */
	public <T> Long count(Class<T> entityClass, Query query) {
		return this.mongoTemplate.count(query, entityClass);
	}
	/**
	 * 
	 * @param collectionName
	 *            集合名称
	 * @param query
	 *            查询条件
	 * @return
	 */
	public <T> Long count(String collectionName, Query query) {
		return this.mongoTemplate.count(query, collectionName);
	}
	
	/**
	 * 批量插入
	 * @param entityClass 对象类
	 * @param collection  要插入的对象集合
	 */
	public <T> void addCollection(Class<T> entityClass, Collection<T> collection){
		this.mongoTemplate.insert(collection, entityClass);
	}

	public MongoTemplate getMongoTemplate() {
		return mongoTemplate;
	}
	
	/**
	 * 统计查询
	 * @param entityClass 对象类
	 * @param collection  要插入的对象集合
	 */
	public <T> GroupByResults<T> group(Criteria criteria,String inputCollectionName,GroupBy groupBy,Class<T> entityClass){
		return this.mongoTemplate.group(criteria, inputCollectionName, groupBy, entityClass);
	}
	/**
	 * 统计查询 排序 加分页
	 * @param entityClass 对象类
	 * @param collection  要插入的对象集合
	 */
	public <T> AggregationResults<T> aggregate(Aggregation aggregation, String inputCollectionName, Class<T> outputType){
		
		return this.mongoTemplate.aggregate(aggregation, inputCollectionName, outputType);
	}
}